/*
 * @Author: zzd993
 * @Date: 2023-02-09 14:46:08
 * @LastEditors: zzd993
 * @LastEditTime: 2023-02-13 16:21:00
 * @FilePath: \手写vue2源码\src\init.js
 * Copyright (c) 2023 by ZZD, All Rights Reserved. 
 */

import { initState } from "./state"
import { compileToFunction } from './compiler/index'
import { callHook, mountComponent } from "./lifecycle"
import { mergeOptions } from "./globalAPI"
export function initMixin(Vue) { // 就是给vue增加init功能
    Vue.prototype._init = function(options) { // 用于初始化操作
        // vm.$options 就是获取用户的设置
        // 在实例上添加options，这样在初始化时一次就可以拿到用户的选项
        // 以后添加新功能时直接用实例上的$options
        const vm = this

        // 我们定义的全局指令和过滤器。。都会挂载到实例上
        vm.$options = mergeOptions(this.constructor.options, options)

        callHook(vm, 'beforeCreate') 

        // 初始化状态
        initState(vm)

        callHook(vm, 'created')
        // 如果用户传入了el属性
        if(options.el) {
            vm.$mount(options.el)  // 实现数据的挂载
        } 
    }
    Vue.prototype.$mount = function(el) {
        const vm = this
        el = document.querySelector(el)
        let ops = vm.$options
        if(!ops.render) { // 先看有没有render函数
            let template // 
            if(!ops.template && el) { // 再看看有没有模板，没有写模板但是写了el
                template = el.outerHTML
            } else {
                // 有模板就用模板
                if(el) {
                    template = ops.template  //如果有el，则采用模板的内容
                }
            }
            if(template) {
                // 这里需要对模板进行编译
                const render =  compileToFunction(template)
                ops.render = render
            }
        }
        // console.log(ops.render); 拿到了render函数

        mountComponent(vm, el)  // 组件的挂载
    }
}